#include "tcp_manager.h"

using namespace std;

tcp_server::tcp_server(short int port) : BR(SOCK_STREAM, (short) port, 0), descMax(0)
{
	if(this->BR.good())
	{ this->descBR = this->BR.getsDesc(); }
	else {
		cout << "Erreur : tcp_server::BR not good()" << endl;
		exit(1);
	}
}

tcp_server::~tcp_server()
{
	for(list<Client *>::iterator it = this->clients.begin(); it != this->clients.end(); ++it)
	{
		delete (*it);
	}
}

void tcp_server::update_fd()
{
	FD_ZERO(&this->set);
	FD_SET(this->descBR, &this->set);
	
	for(list<Client *>::iterator it = this->clients.begin(); it != this->clients.end(); ++it)
	{ FD_SET((*it)->desc, &this->set); }
}

bool tcp_server::tcp_send(string data, int desc)
{
	int size = data.length();
	int res_send = 0;
	
	if(desc != -1)
	{
		res_send = send(desc, &size, sizeof(size), 0);
		if(res_send == -1) { cout << "Erreur : tcp_server::send()" << endl; }
		res_send = send(desc, data.c_str(), data.length(), 0);
		if(res_send == -1) { cout << "Erreur : tcp_server::send()" << endl; }
	}
	else
	{
		for(list<Client *>::iterator it = this->clients.begin(); it != this->clients.end(); ++it)
		{
			res_send = send((*it)->desc, &size, sizeof(size), 0);
			if(res_send == -1) { cout << "Erreur : tcp_server::send()" << endl; }
			res_send = send((*it)->desc, data.c_str(), data.length(), 0);
			if(res_send == -1) { cout << "Erreur : tcp_server::send()" << endl; }
		}
	}
	
	return (res_send != -1);
}


string tcp_server::tcp_recv(int desc)
{
	int size = 0;
	int res_recv;
	
	res_recv = recv(desc, &size, sizeof(size), 0);
	if(res_recv == -1) { cout << "Erreur : tcp_server::recv()" << endl; }
	
	char *msg = new char[size+1];
	
	for(int k(0); k<size; k++)
	{
		res_recv = recv(desc, &msg[k], sizeof(msg[k]), 0);
		if(res_recv == -1) { cout << "Erreur : tcp_server::recv()" << endl; }
	
	}
	
	msg[size] = '\0';
	
	
	/// Deconnexion d'un client
	string s = msg;
	if(s == "/quit") { this->remove_client(desc); }
	/// *****************
	
	return s;
}


void tcp_server::add_client()
{
	Client * cv = new Client;
	
	int res = listen(this->descBR, 5);
	if(res == -1) { cout << "Erreur listen" << endl; }
	
	cv->lg = sizeof(struct sockaddr_in);
	cv->desc = accept(this->descBR, (struct sockaddr*)&cv->BR, &cv->lg);
	
	if(cv->desc == -1)
	{
		cout << "Erreur : tcp_server::add_client()" << endl;
		delete cv;
	}
	else
	{
		this->clients.push_back(cv);
		this->descMax = max(this->descBR + 1, this->descMax);
	}
}

void tcp_server::remove_client(int desc)
{
	for(list<Client *>::iterator it = this->clients.begin(); it != this->clients.end(); ++it)
	{
		if(desc == (*it)->desc)
		{
			this->clients.erase(it);
			return;
		}
	}
}


void tcp_server::run()
{	
	/// Boucle principale :
	while(this->running)
	{	
		/**
		*** **********
		*** Ici il y aura le code :
		*** **********
		**/		
	}
}


void tcp_server::quit(int signal)
{
	this->tcp_send("/quit");
	this->running = false;
}




tcp_client::tcp_client(short int port, char* ip) : BR(SOCK_STREAM, 0), BR_server(ip, (short)port)
{
	if(this->BR.good())
	{
		this->descBR = this->BR.getsDesc();
	}
	else
	{
		cout << "Erreur : constructeur client" << endl;
	}

	this->addr_BR_server = this->BR_server.getAdrDist();
	this->lg_BR_server = sizeof(struct sockaddr_in);

	this->descs.push_back(this->descBR);
}

tcp_client::~tcp_client() {}


void tcp_client::update_fd()
{
	FD_ZERO(&this->set);

	for(list<int>::iterator it = this->descs.begin(); it != this->descs.end(); ++it)
	{ FD_SET((*it), &this->set); }
	
}


bool tcp_client::tcp_send(string data, int desc)
{
	int size = data.length();
	int res_send = 0;
	
	if(desc != -1)
	{
		res_send = send(desc, &size, sizeof(size), 0);
		if(res_send == -1) { cout << "Erreur : tcp_client::send()" << endl; }
		res_send = send(desc, data.c_str(), data.length(), 0);
		if(res_send == -1) { cout << "Erreur : tcp_client::send()" << endl; }
	}

	return (res_send != -1);
}

string tcp_client::tcp_recv(int desc)
{
	int size = 0;
	int res_recv;
	
	res_recv = recv(desc, &size, sizeof(size), 0);
	if(res_recv == -1) { cout << "Erreur : tcp_client::recv()" << endl; }
	
	char *msg = new char[size+1];
	
	for(int k(0); k<size; k++)
	{
		res_recv = recv(desc, &msg[k], sizeof(msg[k]), 0);
		if(res_recv == -1) { cout << "Erreur : tcp_client::recv()" << endl; }
	
	}

	msg[size] = '\0';
	
	
	/// Deconnexion du serveur
	string s = msg;
	if(s == "/quit") { this->quit(desc); }
	/// *****************
	
	return s;
}


void tcp_client::add_stdin()
{
	/// *****************
	/// Erreur possible !
	/// *****************

	this->descs.push_back(0);
}


void tcp_client::run()
{
	/// Boucle principale :
	while(running)
	{
		/**
		*** **********
		*** Ici il y aura le code :
		*** **********
		**/		
	}
	
}


void tcp_client::quit(int signal)
{
	this->tcp_send("/quit", this->descBR);
	this->running = false;
}



/**


	this->sig_quit = new struct sigaction;
	this->sig_quit->sa_handler = this->quit;
	sigaction(SIGINT, this->sig_quit, NULL);


**/




